#include "Terrain/TerrainChunk.h"

namespace PocketSurvival
{
    TerrainChunk::TerrainChunk() : TerrainChunk(0, 0) {}

    TerrainChunk::TerrainChunk(int32_t coordX, int32_t coordY) : 
        coords(coordX, coordY),
        origin(coordX * Terrain::Size, coordY * Terrain::Size),
        center(coordX * Terrain::Size + 8.0f, coordY * Terrain::Size + 8.0f),
        State(TerrainChunkState::NotLoaded),
        isChange(false),
        isRemove(false),
        recycleTime(0.0f)
    {
    }

    void TerrainChunk::initialize(int32_t coordX, int32_t coordY) noexcept
    {
        coords.posX = coordX;
        coords.posY = coordY;
        origin.posX = coordX * Terrain::Size;
        origin.posY = coordY * Terrain::Size;
        center.posX = coordX * Terrain::Size + 8.0f;
        center.posY = coordY * Terrain::Size + 8.0f;
        State = TerrainChunkState::NotLoaded;
        isRemove = false;
        isChange = false;
        recycleTime = 0.0f;
    }

    int32_t TerrainChunk::calculateTopmostCellHeightNoLock(int32_t x, int32_t z)
    {
        int32_t num = CalculateCellIndex(x, 255, z);
        int32_t num2 = 255;
        while (num2 >= 0)
        {
            if (Terrain::ExtractContents(getCellValueFastNoLock(num)) != 0)
            {
                return num2;
            }
            num2--;
            num--;
        }
        return 0;
    }

    bool TerrainChunk::changeOldCellValue(int32_t x, int32_t y, int32_t z, int32_t oldValue, int32_t newValue)
    {
        int32_t index = CalculateCellIndex(x, y, z);
        oldValue = Terrain::ReplaceLight(oldValue, 0);

        std::lock_guard<Recursive_SpinLock> lk(cellValueLock);
        int32_t tarCellValue = Terrain::ReplaceLight(terrainData.cells[index], 0);
        
        if (tarCellValue != oldValue)
        {
            return false;
        }
        terrainData.cells[index] = newValue;
        return true;
    }
}
